package com.xukun.changgou.service.sys.service.impl;

import com.xukun.changgou.common.response.exception.BaseException;
import com.xukun.changgou.service.api.sys.model.PermissionModel;
import com.xukun.changgou.service.api.sys.model.ResourceModel;
import com.xukun.changgou.service.api.sys.model.RoleModel;
import com.xukun.changgou.service.api.sys.vo.RPVo;
import com.xukun.changgou.service.sys.dao.RoleDao;
import com.xukun.changgou.service.sys.service.RoleService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @Author xukun
 * @Date 2021-05-17 13:43
 */
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleDao dao;

    @Override
    public int insert(RoleModel record) {
        int count = dao.selectCount(new RoleModel().setName(record.getName()));
        if (count != 0) {
            throw new BaseException("名称重复");
        }
        int result = dao.insertUseGeneratedKeys(record);
        return result;
    }

    @Override
    public int update(RoleModel record) {
        RoleModel roleModel = dao.selectOne(new RoleModel().setName(record.getName()));
        if (ObjectUtils.isNotEmpty(roleModel) && roleModel.getId() == record.getId()) {
            throw new BaseException("名称重复");
        }
        return dao.updateByPrimaryKeySelective(record);
    }

    @Override
    public int deleteById(Integer id) {
        dao.deleteResourceByRole(id);
        dao.deletePermissionByRole(id);
        return dao.deleteByPrimaryKey(id);
    }

    @Override
    public RoleModel queryOneById(Integer id) {
        RoleModel roleModel = dao.selectByPrimaryKey(id);
        if (ObjectUtils.isEmpty(roleModel)) {
            throw new BaseException("角色不存在");
        }
        return roleModel;
    }

    @Override
    public List<RoleModel> queryList() {
        List<RoleModel> list = dao.queryList();
        return list;
    }

    @Override
    public List<String> queryHasResourceByRole(Integer id) {
        List<ResourceModel> hasResource = dao.queryHasResourceByRoleAndParent(id, 0);

        List<String> rpIds = new ArrayList<>();
        if (ObjectUtils.isNotEmpty(hasResource)) {
            for (ResourceModel resource : hasResource) {
                String rpId = String.valueOf(resource.getId());
                List<ResourceModel> children = dao.queryHasResourceByRoleAndParent(id, resource.getId());
                if (ObjectUtils.isNotEmpty(children)) {
                    queryHasResourceByRole1(rpId, children, rpIds, id);
                } else {
                    //找到对应的权限
                    List<PermissionModel> permissionList = dao.queryHasPermissionByRoleAndResource(id, resource.getId());
                    if (ObjectUtils.isNotEmpty(permissionList)) {
                        for (PermissionModel permissionModel : permissionList) {
                            rpIds.add(rpId + "P" + permissionModel.getId());
                        }
                    }
                }
            }
        }

        return rpIds;
    }

    /**
     * 递归
     *
     * @param rpId        当前传递过来的资源id,用于拼接
     * @param hasResource 根据role查询到的拥有的资源列表
     * @param rpIds       用于递归过程中最终要返回的列表
     * @param roleId      角色id
     */
    private void queryHasResourceByRole1(String rpId, List<ResourceModel> hasResource, List<String> rpIds, Integer roleId) {
        if (ObjectUtils.isNotEmpty(hasResource)) {
            for (ResourceModel resource : hasResource) {
                String rpId1 = rpId + "R" + resource.getId();
                List<ResourceModel> children = dao.queryHasResourceByRoleAndParent(roleId, resource.getId());
                if (ObjectUtils.isNotEmpty(children)) {
                    queryHasResourceByRole1(rpId1, children, rpIds, roleId);
                } else {
                    //找到对应的权限
                    List<PermissionModel> permissionList = dao.queryHasPermissionByRoleAndResource(roleId, resource.getId());
                    if (ObjectUtils.isNotEmpty(permissionList)) {
                        for (PermissionModel permissionModel : permissionList) {
                            rpIds.add(rpId1 + "P" + permissionModel.getId());
                        }
                    }
                }
            }
        }
    }

    @Transactional
    @Override
    public void insertRP(RPVo rpVo) {
        Integer roleId = rpVo.getRoleId();
        String[] rpIds = rpVo.getRpIds();
        //先清空该角色所有的权限
        dao.deleteResourceByRole(roleId);
        dao.deletePermissionByRole(roleId);

        if (ObjectUtils.isNotEmpty(rpIds)) {
            Set<Integer> resourceIds = new HashSet<>();
            Set<Integer> permissionIds = new HashSet<>();

            for (String rpId : rpIds) {
                String[] rp = rpId.split("P");
                if (rp.length == 2) {
                    permissionIds.add(Integer.valueOf(rp[1]));
                }
                String[] rIds = rp[0].split("R");
                if (rIds.length != 0) {
                    for (String rId : rIds) {
                        resourceIds.add(Integer.valueOf(rId));
                    }
                }
            }
            //添加资源
            dao.insertRoleResource(roleId, resourceIds);
            //添加权限
            dao.insertRolePermission(roleId, permissionIds);
        }
    }

}
